package com.shiyingzi.security.service.impl;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.shiyingzi.common.Constants;
import com.shiyingzi.common.EntityUtils;
import com.shiyingzi.common.ResponseData;
import com.shiyingzi.security.dao.MenuDao;
import com.shiyingzi.security.dao.RoleDao;
import com.shiyingzi.security.dao.RoleMenuDao;
import com.shiyingzi.security.dao.UserDao;
import com.shiyingzi.security.dao.UserRoleDao;
import com.shiyingzi.security.model.Menu;
import com.shiyingzi.security.model.Role;
import com.shiyingzi.security.model.RoleMenu;
import com.shiyingzi.security.model.User;
import com.shiyingzi.security.model.UserRole;
import com.shiyingzi.security.service.ISecurityUserService;
import com.shiyingzi.utils.MDFiveUtils;

@Service(ISecurityUserService.BEAN_ID)
public class SecurityUserServiceImpl  implements ISecurityUserService{

	@Autowired
	private UserDao userDao;
	@Autowired
	private MenuDao menuDao;
	@Autowired
	private RoleDao roleDao;
	@Autowired
	private RoleMenuDao roleMenuDao;
	@Autowired
	private UserRoleDao userRoleDao;
	
//	@Resources
	
	
	@Autowired
	private HttpSession session;
	
	
	public ResponseData doLogin(User user) {
		User user2  =new User();
		user2.setUserName(user.getUserName());
		User userDB = userDao.selectOne(user2);
		if(userDB == null){
			return new ResponseData(false, "用户帐户不存在");
		}else{
			if(MDFiveUtils.encrypt(StringUtils.trim(user.getUserPassword())).equals(userDB.getUserPassword())){
				session.setAttribute(Constants.SESSION_USER, userDB);
				return new ResponseData(true, "登录成功");
			}else{
				return new ResponseData(false, "用户名密码错误");
			}
		}
	}


	@Override
	public User getUserById(Integer id) {
		User one = userDao.selectById(id);
		return one;
	}


	@Override
	public User modifyUser(User user) {
		EntityUtils.modifyEntity(user, session);
		userDao.insert(user);
		setUserRole(user, user.getRoles());
		return user;
	}


	@Override
	public User deleteUser(User user) {
		EntityUtils.deleteEntity(user, session);
		userDao.insert(user);
		return user;
	}


	@Override
	public List<Role> getRolesByUser(User user) {
		
		List<UserRole> listUserRole = userRoleDao.selectList(new EntityWrapper<UserRole>().eq("user_id", user.getId()));
		List<Integer> ids = new ArrayList<Integer>();
		for (UserRole userRole : listUserRole) {
			ids.add(userRole.getRoleId());
		}
		List<Role> listRole = roleDao.selectList(new EntityWrapper<Role>().in("id", ids));
		return listRole;
	}

	@Override
	public List<Role> getAllRoles() {
		return roleDao.selectList(null);
	}

	@Override
	public List<User> getUsersByRole(Role role) {
		List<UserRole> listUserRole =  userRoleDao.selectList(new EntityWrapper<UserRole>().eq("role_id", role.getId()));
		List<Integer> ids = new ArrayList<Integer>();
		for (UserRole UserRole : listUserRole) {
			ids.add(UserRole.getUserId());
		}
		List<User> listUser = userDao.selectList(new EntityWrapper<User>().in("id", ids));
		return listUser;
	}


	@Override
	public List<Menu> getMenusByRole(Role role) {
		List<RoleMenu> listRoleMenu = roleMenuDao.selectList(new EntityWrapper<RoleMenu>().eq("role_id", role.getId()));
		List<Integer> ids = new ArrayList<Integer>();
		for (RoleMenu RoleMenu : listRoleMenu) {
			ids.add(RoleMenu.getMenuId());
		}
		//获取第一级菜单
		List<Menu> listMenu = menuDao.selectList(new EntityWrapper<Menu>().isNull("parent_id").and().in("id", ids));
		for (Menu Menu : listMenu) {
			//获取一级菜单的子菜单，目前仅限二级菜单
			Menu.setChlidMenus(menuDao.selectList(new EntityWrapper<Menu>().eq("parent_id", Menu.getId()).and().in("id", ids)));
		}
		return listMenu;
	}


	@Override
	public User addUser(User user) {
		EntityUtils.initEntity(user, session);
		user.setUserPassword(MDFiveUtils.encrypt("admin"));
		userDao.insert(user);
		setUserRole(user, user.getRoles());
		return user;
	}
	
	private void setUserRole(User user, String[] roles){
		if(roles != null && roles.length > 0){
			List<Role> doAddRole = new ArrayList<>();
			for(String s : roles){
				if(StringUtils.isNumeric(s)){
//					try {
						Role roleById = this.getRoleById(Integer.parseInt(s));
						doAddRole.add(roleById);
//					} catch (EntityNotFoundException e) {
//						e.printStackTrace();
//					}
				}
			}
			List<Role> rolesByUser = this.getRolesByUser(user);
			List<Role> tempRolesByUser = new ArrayList<Role>();
			tempRolesByUser.addAll(rolesByUser);
			//获取差集删除
			rolesByUser.removeAll(doAddRole);
			for (Role Role : rolesByUser) {
//				findByUserIdAndRoleId(user.getId(), Role.getId());
				List<UserRole> delRoles = userRoleDao.selectList(new EntityWrapper<UserRole>().eq("role_id", Role.getId()).eq("user_id", user.getId()));   
				for (UserRole UserRole : delRoles) {
					EntityUtils.deleteEntity(UserRole, session);
				}
				userRoleDao.updateBatchUserRole(delRoles);
			}
			
			//获取差集新增
			doAddRole.removeAll(tempRolesByUser);
			for (Role Role : doAddRole) {
				UserRole userRole = new UserRole();
				EntityUtils.initEntity(userRole, session);
				userRole.setRoleId(Role.getId());
				userRole.setUserId(user.getId());
				userRoleDao.insert(userRole);
			}
		}
	}


	@Override
	public Role getRoleById(Integer id) {
		Role role = roleDao.selectById(id);
		return role;
	}


	@Override
	public List<Menu> getMenusByCurrentUser() {
		User user = EntityUtils.getSessionUser(session);
		//获取当前用户角色
		List<Role> listRoles = this.getRolesByUser(user);
		//获取角色对应的菜单
		List<Menu> listMenu = new ArrayList<>();
		for (Role Role : listRoles) {
			List<Menu> menus = this.getMenusByRole(Role);
			menus.removeAll(listMenu);
			listMenu.addAll(menus);
		}
		return listMenu;
	}


	@Override
	public Menu addMenu(Menu menu) {
		EntityUtils.initEntity(menu, session);
		System.out.println(menu);
		menuDao.insert(menu);
		return menu;
	}


	@Override
	public Menu modifyMenu(Menu menu) {
		EntityUtils.modifyEntity(menu, session);
		System.out.println(menu);
		 menuDao.updateById(menu);
		return menu;
	}


	@Override
	public Menu deleteMenu(Menu menu) {
		EntityUtils.deleteEntity(menu, session);
		menuDao.deleteById(menu);
		return menu;
	}


	@Override
	public Menu getMenuById(Integer id) {
		return menuDao.selectById(id);
	}


	@Override
	public Role addRole(Role role) {
		EntityUtils.initEntity(role, session);
		roleDao.insert(role);
		return role;
	}


	@Override
	public Role modifyRole(Role role) {
		EntityUtils.modifyEntity(role, session);
		roleDao.updateById(role);
		return role;
	}


	@Override
	public Role deleteRole(Role role) {
		EntityUtils.deleteEntity(role, session);
		roleDao.deleteById(role.getId());
		return role;
	}


	@Override
	public List<Menu> getAllMenuByRoleId(Integer roleId) {
		Role role = this.getRoleById(roleId);
		List<Menu> menusByCurrentUser = this.getMenusByRole(role);
		List<Menu> menu = menuDao.selectList(new EntityWrapper<Menu>().isNull("parent_id"));
		for (Menu Menu : menu) {
			if(CollectionUtils.contains(menusByCurrentUser.iterator(), Menu)){
				Menu.setEnable(true);
			}
			List<Menu> childMenu = menuDao.selectList(new EntityWrapper<Menu>().eq("parent_id", Menu.getId()));
			for (Menu child : childMenu) {
				for(Menu userChild : menusByCurrentUser){
					if(CollectionUtils.contains(userChild.getChlidMenus().iterator(), child)){
						child.setEnable(true);
					}
				}
			}
			Menu.setChlidMenus(childMenu);
		}
		return menu;
	}


	@Override
	public ResponseData doUpdateRoleMenu(RoleMenu menu, boolean checked) {
		List<RoleMenu> listMenu = roleMenuDao.selectList(new EntityWrapper<RoleMenu>(menu));
		if(checked){
			if(CollectionUtils.isEmpty(listMenu)){
				EntityUtils.initEntity(menu, session);
				roleMenuDao.insert(menu);
			}
		}else{
			if(!CollectionUtils.isEmpty(listMenu)){
				for (RoleMenu RoleMenu : listMenu) {
					EntityUtils.deleteEntity(RoleMenu, session);
					roleMenuDao.updateById(RoleMenu);
				}
			}
		}
		return new ResponseData(true);
	}

/**
 * 修改状态
 */
	@Override
	public User modifyUser1(User user) {
		EntityUtils.modifyEntity(user, session);
		userDao.updateById(user);
		return user;
	}
}
